Raspberry Pi door bell

I’ve always wanted a door bell that could e-mail me a picture whenever someone came to my door. This should be fairly easy using a Raspberry Pi, so I built one. Here’s the build log and code if you would like to build one yourself.

Raspberry Pi

The core of this door bell is a Raspberry Pi, a small form factor and cheap computer board. I’m using the Raspi Model B+, although nowadays a newer and improved Model 2 is available.

To capture images a camera module is attached to the Raspi.

Power supply

The Raspi is powered from my houses’ 12VDC bus through an LM2596 switching regulator, which drops the voltage down to the 5V needed by the Raspi. This regulator can supply up to 3A and can easily be found on your favourite action site.

The power is supplied to one of the 5V pins on the GPIO header.

Hooking up the doorbell’s buttons

My door bell has 4 buttons, one for each person living in the house. This way we can have different ring tones depending on who the visit is calling for.

The 4 buttons are connected to the Raspi GPIO pins. The buttons have 100 Ohm series resistors to protect the GPIO pins in case I accidentally short-circuit them or put power onto them.

1.5k pull-up resistors keep the GPIO pins pulled up, when a button is pressed it pulls the corresponding GPIO pin down.

Python script

The door bell functionality is programmed into a Python script.

EMAIL='xxxxxx@gmail.com'

This variable sets the address where the e-mail appears to be sent from.

GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)

Sets the GPIO pin numbering scheme to BCM and disables pin warnings.

GPIO.setup(14, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.setup(15, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.setup(17, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.setup(18, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.setup(4, GPIO.OUT, pull_up_down=GPIO.PUD_DOWN)

These statements set the pin direction (inputs or outputs) and enables the internal pull-down resistor.

def internet_on():
	try:
		response=urllib2.urlopen('http://www.google.com',timeout=10)
		return True
	except urllib2.URLError as err: pass
	return False
    
if internet_on()==True:
	print "Internet is set up :)"
else:
	print "No internet"

Check if we have internet connection.

while True:
	if GPIO.input(14) or GPIO.input(15) or GPIO.input(18) or GPIO.input(17): #button pressed
		if GPIO.input(14): 
			calling="name1"
		if GPIO.input(15): 
			calling="name2"
		if GPIO.input(17): 
			calling="name3"
		if GPIO.input(18): 
			calling="name4"

    time1=strftime("%H:%M on %a %d %b '%y")
    message="Ding Dong at "+time1
    time2=strftime("%Y, %m, %d, %H, %M, %S")

    print "Button pressed for", calling, "at", time1

command="sudo echo "+strftime("%Y, %m, %d, %H, %M, %S")+", "+calling+" >> /fileshare/doorbell/log.csv"
    os.system(command) 
command="sudo echo "+strftime("%Y/%m/%d at %H:%M:%S for ")+calling+" >> //fileshare/doorbell/log.txt"
    os.system(command) 
        
#os.system("./call.sh")

GPIO.output(4,1)  # doorbell (siren) on

    os.system("sudo python camera.py")

GPIO.output(4,0)  # doorbell (siren) off

    os.system("sudo python camera-highres.py")

GPIO.output(4,1)  # doorbell (siren) on

command="sudo python send_email_attachment.py"
    os.system(command) 

GPIO.output(4,0)  # doorbell (siren) off

#        os.system("sudo python send_email_attachment.py") 
  
#        os.system("sudo python zapier_webhook.py"+ time2) #put a space within the quote after .py to insert an argument

#        os.system('sudo echo '+message+' | sendxmpp -v -t ' + EMAIL) #send hangouts message
#        os.system("sudo python tweet.py ")
    
    time.sleep(0.2)
    print "\nWaiting for button..."


#Local video
#    if lcd.buttonPressed(lcd.LEFT):
#        proc = subprocess.Popen([ "raspivid -t 0 -b 2000000 -n -o - | gst-launch-1.0 -e -vvvv fdsrc ! h264parse ! flvmux ! rtmpsink location=rtmp://localhost/rtmp/live"],  shell=True)
#        print("aa")
#        (out, err) = proc.communicate()
#        print "program output:", out

#    if lcd.buttonPressed(lcd.RIGHT):
#        print("aa")
#        proc = subprocess.Popen(["pkill gst-launch-1.0; pkill raspivid"], shell=True)
#        (out, err) = proc.communicate()
#        print "program output:", out
#os.system("raspivid -o - -t 0 -w 1270 -h 720 -fps 25 -b 600000 -g 50 | ./ffmpeg -re -ar 44100 -ac 2 -acodec pcm_s16le -f s16le -ac 2 -i /dev/zero -f h264 -i - -vcodec copy -acodec aac -ab 128k -g 50 -strict experimental -f flv rtmp://a.rtmp.youtube.com/live2/DoorBellDing.rpt9-wuhk-ctju-dgxw")

#        proc = subprocess.Popen([ "/sbin/ifconfig wlan0 | grep 'inet addr:' | cut -d: -f2 | awk '{ print $1}'"], stdout=subprocess.PIPE, shell=True)
#        (out, err) = proc.communicate()
    #print "program output:", out

Start Doorbell script at startup

There are loads of ways of running a command at start-up in Linux. Here we’ll create an initialisation script in /etc/init.d and register it using update-rc.d. This way the application is started and stopped automatically when the system boots / shuts down.

Create script in /etc/init.d

sudo nano /etc/init.d/startDoorbell.sh

The following is an example based on starting up my doorbell script, but change the name of the script and the command to start and stop it, and it would work for any command.

#! /bin/sh

# Carry out specific functions when asked to by the system
case "$1" in
start)
	echo "Starting Doorbell script"
	# run application you want to start
	/home/webide/repositories/my-pi-projects/Doorbell/python /home/webide/repositories/my-pi-projects/Doorbell/main.py
	;;
stop)
	echo "Stopping Doorbell script"
	# kill application you want to stop
#    killall python
;;
*)
	echo "Usage: /etc/init.d/noip {start|stop}"
	exit 1
	;;
esac

exit 0

Warning - its important you test your script first and make sure it doesn’t need a user to provide a response, press “y” or similar, because you may find it hangs the Raspberry Pi on boot waiting for a user (who’s not there) to do something!

Make script executable:

sudo chmod 755 /etc/init.d/startDoorbell.sh

Test starting the program:

sudo /etc/init.d/startDoorbell.sh start

Test stopping the program:

sudo /etc/init.d/startDoorbell.sh stop

To register your script to be run at start-up and shutdown, run the following command:

sudo update-rc.d startDoorbell.sh defaults

Note - The header at the start is to make the script LSB compliant and provides details about the start up script and you should only need to change the name. If you want to know more about creating LSB scripts for managing services, see http://wiki.debian.org/LSBInitScripts

If you ever want to remove the script from start-up, run the following command:

sudo update-rc.d -f  startDoorbell.sh remove

As per this tutorial

Mounting

All hardware is fixed to a mounting plate in a riser next to my front door. This way the cable between the Raspi and its camera can be kept fairly short (45cm).

Comments